package com.fantasy.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fantasy.blog.dao.mapper.ArticleMapper;
import com.fantasy.blog.dao.mapper.CommentMapper;
import com.fantasy.blog.dao.pojo.Comment;
import com.fantasy.blog.dao.pojo.SysUser;
import com.fantasy.blog.service.*;
import com.fantasy.blog.utils.UserThreadLocal;
import com.fantasy.blog.vo.CommentVo;
import com.fantasy.blog.vo.ErrorCode;
import com.fantasy.blog.vo.Result;
import com.fantasy.blog.vo.UserVo;
import com.fantasy.blog.vo.params.CommentParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class CommentsServiceImpl implements CommentsService {

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private ThreadService threadService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private MailService mailService;

    @Override
    public Result comments(Long id) {
        /**
         * 1.根据文章查询评论列表 从 comment 中查询
         * 2.根据作者id查询作者信息
         * 3.如果level等于一，是否有子评论
         * 4.有，则根据评论id来查询
         */
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        /*
            先只查询leval为一的
         */
        queryWrapper.eq(Comment::getArticleId,id)
                        .eq(Comment::getLevel,1);
        List<Comment> comments = commentMapper.selectList(queryWrapper);
        List<CommentVo> commentVos = copyList(comments);
        return Result.success(commentVos);
    }

    @Override
    public Result comment(CommentParam commentParam) {
        Comment comment = new Comment();
        comment.setArticleId(commentParam.getArticleId());

        String qq = commentParam.getQq();
        String email = commentParam.getEmail();
        qq = String.valueOf(qq);
        email = String.valueOf(email);
        //判断是否合法
        String emailRule = "[\\w'.%+-]+@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,4}";
        String qqRule = "[1-9][0-9]{4,14}";

        System.out.println("QQ: "+ qq+"\nemali: "+email);

        Pattern patternQQ = Pattern.compile(qqRule);
        Pattern patternEmail = Pattern.compile(emailRule);
        Matcher matcherQQ = patternQQ.matcher(qq);
        Matcher matcherEmail = patternEmail.matcher(email);
        if(!matcherQQ.matches()||!matcherEmail.matches()){
            System.out.println(matcherQQ.matches()+" "+matcherEmail.matches());
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }
        //通过qq查询是否在数据库中
        SysUser sysUser = sysUserService.findUserByQQ(qq);

        //没有则创建
        if(sysUser==null){
            try {
                sysUser = sysUserService.creatUserByQQ(qq,email);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        assert sysUser != null;

        comment.setAuthorId(sysUser.getId());
        comment.setContent(commentParam.getContent());
        comment.setCreateDate(System.currentTimeMillis());
        Long parent = commentParam.getParent();
        boolean isTome = false;
        if (parent == null || parent == 0) {
            comment.setLevel(1);
            isTome = true;
        }else{
            comment.setLevel(2);
        }
        comment.setParentId(parent == null ? 0 : parent);
        Long toUserId = commentParam.getToUserId();
        comment.setToUid(toUserId == null ? 0 : toUserId);
        comment.setEmail(email);
        this.commentMapper.insert(comment);

        this.threadService.updateCommentCountById(commentParam.getArticleId());

        if (isTome){
            mailService.sendSimpleMail("421791975@qq.com",
                "博客消息回复通知"
                    ,"有人在博客下回复了您,请到"+commentParam.getArticleId()+"查阅\n"+"回复内容为："+comment.getContent())   ;
        }else {
            String toEmail = findEmailById(commentParam.getToCommentId());
            mailService.sendSimpleMail(toEmail,
                    "博客消息回复通知"
                    ,"有人在博客下回复了您,请到"+commentParam.getArticleId()+"查阅\n"+"回复内容为："+comment.getContent())   ;

        }

//        mailService.sendSimpleMail();

        return Result.success(null);
    }

    private String findEmailById(Long id){
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Comment::getEmail)
                .eq(Comment::getId,id)
                .last("limit 1");
        return commentMapper.selectOne(queryWrapper).getEmail();
    }

    private List<CommentVo> copyList(List<Comment> comments) {
        List<CommentVo> commentVoList = new ArrayList<>();
        for (Comment comment : comments) {
            commentVoList.add(copy(comment));
        }
        return commentVoList;
    }

    private CommentVo copy(Comment comment) {
        CommentVo commentVo = new CommentVo();
        BeanUtils.copyProperties(comment,commentVo);
        Long authorId = comment.getAuthorId();

        UserVo userVo = sysUserService.findUserVoById(authorId);
        commentVo.setAuthor(userVo);

        //子评论
        Integer level = comment.getLevel();
        if(1 == level){
            Long id = comment.getId();
            List<CommentVo> commentsChildren = findcommentsByParentId(id);
            commentVo.setChildren(commentsChildren);
        }

        if(level>1){
            Long toUid = comment.getToUid();
            UserVo toUserVo = sysUserService.findUserVoById(toUid);
            commentVo.setToUser(toUserVo);
        }

        return commentVo;
    }

    private List<CommentVo> findcommentsByParentId(Long id) {
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Comment::getParentId,id)
                    .eq(Comment::getLevel,2);

        List<Comment> comments = commentMapper.selectList(queryWrapper);
        return copyList(comments);
    }
}
